package main

import (
    "fmt"
    "reflect"
)

type Student struct {
	Name 	string `json:"name"`
	Age  	int    `json:"age"`
	Score int    `json:"score"`
}

func (s Student) GetInfo() string {
	return fmt.Sprintf("name:%s, age:%d, score:%d", s.Name, s.Age, s.Score)
}

func (s * Student) Constructor(name string, age int, score int) {
	s.Name = name
	s.Age = age
	s.Score = score
}

func reflectChangeStruct(x interface{}) {
	// 由于要修改属性，所以这里必须要求传入的是指针
	t := reflect.TypeOf(x)
	k := t.Kind()
	if (k != reflect.Ptr) {
		fmt.Println("传入必须是结构体的指针")
		return
	}
	e := t.Elem()
	// fmt.Printf("%#v\n", e)
	tek := e.Kind()
	// 要求必须传入结构体的指针
	if (tek != reflect.Struct) {
		fmt.Println("传入必须是结构体的指针")
		return
	}
	fmt.Println("传入的参数正确")

	// 修改结构体属性的值
	// 先获取对应属性的reflect.Value
	v := reflect.ValueOf(x)
	name := v.Elem().FieldByName("Name")
	if name.IsValid() {
		name.SetString("Jerry")
	}
	age := v.Elem().FieldByName("Age")
	if age.IsValid() {
		age.SetInt(20)
	}
	score := v.Elem().FieldByName("Score")
	if score.IsValid() {
		score.SetInt(100)
	}

}

func main() {
	// var a = 10
	// reflectChangeStruct(&a)

	var stu = Student{
		Name: "Tom",
		Age:  18,
		Score: 80,
	}
	fmt.Printf("%#v\n", stu)
	reflectChangeStruct(&stu)
	fmt.Printf("%#v\n", stu)

}